/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rhythm.commons.net;

import com.sun.mail.pop3.POP3Message;
import com.sun.mail.smtp.SMTPMessage;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;

public class Pop3Emailer
{

    public static final String PROPS_SMTP_HOST = "mail.smtp.host";

    private static final String INBOX_NAME = "INBOX";

    private static final String PROPS_POP3_HOST = "mail.pop3.host";

    private static final String STORE_NAME = "pop3";

    private Properties props;

    private Session session;

    private Store store;

    /**
     * Creates a new instance of a <code>Pop3Emailer</code> for the 
     * given mail host. E.g. 'mail.hostname.com'
     * @param mailHost a valid host name
     * @return a new instance of a <code>Pop3Emailer</code>
     */
    public static Pop3Emailer of(final String mailHost) {
        return new Pop3Emailer(mailHost);
    }

    private Pop3Emailer(final String hostName) {
        createMailServerSettings(hostName);
    }

    public SimpleEmailMessage createMessage(String username, String password) {
        Authenticator authenticator = new EmailPasswordAuthenticator(username, password);
        return new SimpleEmailMessage(Session.getInstance(this.props, authenticator));
    }

    /**
     * Attempts to send a instance of a <code>EmailMessage</code>.
     * 
     * @param emailMessage a valid instance of a <code>EmailMessage</code>.
     * @throws MessagingException 
     */
    public void send(SimpleEmailMessage emailMessage) throws MessagingException {

        //MimeMessage message = new  MimeMessage(emailMessage.getSession());
        Message message = new SMTPMessage(emailMessage.getSession());
        
        message.setFrom(new InternetAddress(emailMessage.getSender()));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(emailMessage.getRecepient()));
        message.setSubject(emailMessage.getSubject());
        message.setText(emailMessage.getBody());

        Transport.send(message);
    }


//    public Pop3Emailer(String mailHost, String username, String password) {
//        createMailServerSettings(mailHost);
//
//        Authenticator auth = new EmailPasswordAuthenticator(username, password);
//
//        this.session = Session.getInstance(this.props, auth);
//    }

    public boolean isSubjectEqual(Message message, String string) {
        try
        {
            return message.getSubject().equals(string);
        } catch (MessagingException ex)
        {
            return false;
        }
    }

    /**
     * Verifies that the expected email is found, the match is based on the subject line, if the message 
     * is found then it will be marked for deletion and cleared the when the folder is closed
     * @param expectedSubject Expected subject line
     * @param timeoutInSeconds 
     * @return boolean returns true if a matching message is found within the timeout period
     * @throws java.lang.Exception
     */
    public boolean verifyRecievedMessage(String expectedSubject, int timeoutInSeconds) throws Exception {
        this.store = this.session.getStore(STORE_NAME);
        this.store.connect();

        //convert from seconds to milliseconds
        int timeout = timeoutInSeconds * 1000;
        int timeSpent = 0;
        try
        {
            while (timeSpent < timeout)
            {
                if (this.checkForMatchingEmail(expectedSubject))
                    return true;
                else
                {
                    java.lang.Thread.sleep(3000);
                    timeSpent += 3000;
                }
            }
        } finally
        {
            this.store.close();
        }

        return false;
    }

    private boolean checkForMatchingEmail(String expectedSubject) throws MessagingException {
        Folder folder = this.store.getFolder(INBOX_NAME);
        //opened read write which allows us to delete the file, if found
        folder.open(Folder.READ_WRITE);
        try
        {
            Message message[] = folder.getMessages();
            for (int i = 0; i < message.length; i++)
            {
                if (this.isSubjectEqual(message[i], expectedSubject))
                {
                    message[i].setFlag(Flags.Flag.DELETED, true);
                    return true;
                }
            }
        } finally
        {
            folder.close(true);
        }
        return false;
    }

    private void createMailServerSettings(String mailHost) {
        this.props = System.getProperties();
        this.props.put(PROPS_POP3_HOST, mailHost);
        this.props.put(PROPS_SMTP_HOST, mailHost);
    }
}
